namespace ObjectPersistence {
    using System;
    using System.Text;
    using System.Collections;
    using System.Data.Common;
    using System.Transactions;
    using System.Collections.Generic;
    
    public partial class UserAssembler : AssemblerBaseUpdatable<KYO.DAL.User, UserCriteria, UserRowMap, UserDomainObjectFactory> {
        public UserAssembler() {
            base.connection = new System.Data.SqlClient.SqlConnection(GlobalUtil.Constants.ConnectionString);
        }
        protected override System.Data.Common.DbConnection InstanceConnection {
            get {
                return this.connection;
            }
        }
        /// <summary>Reads a single object from the database corresponding to the object keys which are passed in</summary>
        public KYO.DAL.User ReadSingleByKey(int UserID) {
            UserCriteria criteria = new UserCriteria();
            criteria.Set_UserID(UserCriteria.AVAILABLE_OPERATORS.EQUALS, UserID);
            return this.ReadSingle(criteria);
        }

        internal override void MakePersistent(KYO.DAL.User PersistentObject, bool cascade, System.Data.Common.DbCommand comm) {
            if ((PersistentObject.IsNew == false)) {
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) 
                            && (PersistentObject.ChangesMade == false))) {
                    return;
                }
                if ((GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Contains(PersistentObject.ROKeyString) == false)) {
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                }
            }

            if ((PersistentObject.IsNew || PersistentObject.ChangesMade)) {
                UserUpdateFactory updateFactory = new UserUpdateFactory();
                comm.Parameters.Clear();
                if ((PersistentObject.IsNew == false)) {
                    updateFactory.updateCommandText(PersistentObject, comm);
                    int numRows = comm.ExecuteNonQuery();
                    if ((numRows == 0)) {
                        throw new NoRowsUpdated();
                    }
                }
                else {
                    updateFactory.insertCommandText(PersistentObject, comm);
                    comm.CommandText = (comm.CommandText + "; SELECT SCOPE_IDENTITY();");
                    decimal NewIdentityKey = ((decimal)(comm.ExecuteScalar()));
                    PersistentObject.UserID = ((int)(NewIdentityKey));
                    GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Add(PersistentObject.ROKeyString);
                    PersistentObject.IsNew = false;
                }
            }
            PersistentObject.ChangesMade = false;
            if (cascade) {
                RoleAssembler tempRoleAssembler = new RoleAssembler();

                if ((PersistentObject.IsRoleCollNull() == false)) {
                    for (int i1 = 0; (i1 < PersistentObject.RoleColl.Count); i1 = (i1 + 1)) {
                        comm.Parameters.Clear();
                        tempRoleAssembler.MakePersistent(PersistentObject.RoleColl[i1], cascade, comm);
                    }
                    PersistentObject.RoleColl.Clean();
                    this.InsertAddedRoleCollMappingTable(PersistentObject, comm);
                    this.RemoveDeletedRoleCollMappingTableEntries(PersistentObject, comm);
                    PersistentObject.RoleColl.Synch();
                }
                tempRoleAssembler.Dispose();
            }
        }

        internal override void Delete(KYO.DAL.User PersistentObject, System.Data.Common.DbCommand comm) {
            this.DeleteRoleCollMappingTable(PersistentObject, comm);

            comm.Parameters.Clear();

            UserSelectionFactory tempUserSelectionFactory = new UserSelectionFactory();
            string sql = "DELETE FROM [dbo].[User]";
            comm.CommandText = sql;
            tempUserSelectionFactory.getDefaultSelection(PersistentObject, comm);
            comm.ExecuteNonQuery();
        }

        #region Manage Mapping Tables
        private void InsertAddedRoleCollMappingTable(KYO.DAL.User PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "IF NOT EXISTS (SELECT 1 FROM [dbo].[UserInRole] (nolock) WHERE [RoleId] = @rarg0 " +
                "AND [UserId] = @larg1) INSERT INTO [dbo].[UserInRole] ([RoleId] , [UserId] ) VAL" +
                "UES (@rarg0, @larg1)";
            for (int i = 0; (i < PersistentObject.RoleColl.Added.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@larg1", PersistentObject.UserID);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg0", PersistentObject.RoleColl.Added[i].RoleId);
                comm.ExecuteNonQuery();
            }
        }

        private void DeleteRoleCollMappingTable(KYO.DAL.User PersistentObject, System.Data.Common.DbCommand comm) {
            comm.Parameters.Clear();
            comm.CommandText = "DELETE FROM [dbo].[UserInRole] WHERE [UserId]=@arg1";
            ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", PersistentObject.UserID);
            comm.ExecuteNonQuery();
        }

        private void RemoveDeletedRoleCollMappingTableEntries(KYO.DAL.User PersistentObject, System.Data.Common.DbCommand comm) {
            comm.CommandText = "DELETE FROM [dbo].[UserInRole] WHERE  [RoleId]=@rarg0 AND  [UserId]=@arg1";
            for (int i = 0; (i < PersistentObject.RoleColl.Deleted.Count); i = (i + 1)) {
                comm.Parameters.Clear();
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", PersistentObject.UserID);
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@rarg0", PersistentObject.RoleColl.Deleted[i].RoleId);
                comm.ExecuteNonQuery();
            }
        }
        #endregion

        #region Manage Child Objects / Collections
        /// Reads the KYO.DAL.Role from the database corresponding to the object keys passed as parameters
        // <param name="local">Corresponds to User attribute </param
        // <param name="localUserID">Corresponds to User attribute UserID</param
        public BusinessLayerHelper.PersistentList<KYO.DAL.Role> GetRoleColl(int localUserID) {
            BusinessLayerHelper.PersistentList<KYO.DAL.Role> result = new BusinessLayerHelper.PersistentList<KYO.DAL.Role>();
            System.Data.Common.DbConnection tempConnection = this.InstanceConnection;
            try {
                tempConnection.Open();
                System.Data.Common.DbCommand comm = tempConnection.CreateCommand();
                comm.CommandText = (RoleAssembler.SELECT + " FROM [dbo].[UserInRole] INNER JOIN [dbo].[Role] ON [dbo].[UserInRole].[RoleId] =" +
                    " [dbo].[Role].[RoleId] WHERE [dbo].[UserInRole].[UserId] = @arg1");
                ObjectPersistenceHelper.AddParameterWithValue(comm, "@arg1", localUserID);
                RoleAssembler _tempAssem = new RoleAssembler();
                result.FillData(_tempAssem.ReadCollectionCustom(comm));
            }
            finally {
                tempConnection.Close();
            }
            return result;
        }
        #endregion

        #region Helper Utilities
        protected override UserRowMap fillRowMap(System.Data.Common.DbDataReader reader) {
            UserRowMap result = new UserRowMap();
            result.UserID = reader.GetInt32(reader.GetOrdinal("dboUserDOTUserID"));
            result.Password = reader.GetString(reader.GetOrdinal("dboUserDOTPassword"));
            result.Username = reader.GetString(reader.GetOrdinal("dboUserDOTUsername"));
            if ((reader.IsDBNull(reader.GetOrdinal("dboUserDOTFullName")) == false)) {
                result.FullName = reader.GetString(reader.GetOrdinal("dboUserDOTFullName"));
            }
            if ((reader.IsDBNull(reader.GetOrdinal("dboUserDOTImageUrl")) == false)) {
                result.ImageUrl = reader.GetString(reader.GetOrdinal("dboUserDOTImageUrl"));
            }
            return result;
        }
        internal override void ClearList() {
            GlobalUtil.Constants.ObjectMapKYOPHUONGDOPC.Clear();
        }

        public override string Abstract_SELECT {
            get {
                return ("SELECT " + UserAssembler.RawFields);
            }
        }
        protected override string InstanceTable {
            get {
                return "[dbo].[User]";
            }
        }
        public const string RawFields = "[dbo].[User].[UserID] AS dboUserDOTUserID, [dbo].[User].[FullName] AS dboUserDOTF" +
            "ullName, [dbo].[User].[ImageUrl] AS dboUserDOTImageUrl, [dbo].[User].[Password] " +
            "AS dboUserDOTPassword, [dbo].[User].[Username] AS dboUserDOTUsername";
        public const string SELECT = "SELECT [dbo].[User].[UserID] AS dboUserDOTUserID, [dbo].[User].[FullName] AS dboU" +
            "serDOTFullName, [dbo].[User].[ImageUrl] AS dboUserDOTImageUrl, [dbo].[User].[Pas" +
            "sword] AS dboUserDOTPassword, [dbo].[User].[Username] AS dboUserDOTUsername";
        #endregion
    }
}
